package com.platform.core.security.auth;

import cn.hutool.core.map.MapUtil;
import com.platform.comm.config.properties.JwtProperties;
import com.platform.comm.jwt.JwtTokenUtil;
import com.platform.comm.util.CommonWriter;
import com.platform.comm.util.RedisUtil;
import com.platform.comm.web.results.JsonResult;
import com.platform.uaa.controller.AuthController;
import io.jsonwebtoken.Claims;
import org.apache.logging.log4j.util.Strings;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * Description: 自定义登出
 *
 * @author sunzhubin.zh Created on 2019/7/19
 **/
@Component
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {

    private final JwtTokenUtil jwtTokenUtil;
    private final JwtProperties jwtProperties;
    private final StringRedisTemplate redisTemplate;
    private final RedisUtil redisUtil;

    public CustomLogoutSuccessHandler(JwtTokenUtil jwtTokenUtil, JwtProperties jwtProperties, StringRedisTemplate redisTemplate, RedisUtil redisUtil) {
        this.jwtTokenUtil = jwtTokenUtil;
        this.jwtProperties = jwtProperties;
        this.redisTemplate = redisTemplate;
        this.redisUtil = redisUtil;
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest request,
                                HttpServletResponse response,
                                Authentication authentication) throws IOException {
        Claims claims = jwtTokenUtil.getClaimsFromToken(request.getHeader(jwtProperties.getHeader()).replace(jwtProperties.getTokenHead(), Strings.EMPTY));
        // jwt的唯一标识
        String jti = MapUtil.getStr(claims, jwtProperties.getJwtJti());
        // jwt过期时间
        Long expireTime = MapUtil.getLong(claims, jwtProperties.getJwtExp());
        if (expireTime != null) {
            long currentTime = System.currentTimeMillis() / 1000;
            if (expireTime > currentTime) {
                redisTemplate.opsForValue().set("auth:token:blacklist:" + jti, "", (expireTime - currentTime), TimeUnit.SECONDS);
            }
        } else {
            redisTemplate.opsForValue().set("auth:token:blacklist:" + jti, null);
        }
        // 删除在线用户redis缓存
        redisUtil.del(AuthController.LOGIN_TOKEN_KEY + jti);
        CommonWriter.write(JsonResult.success(), response);
    }
}
